Support allocators with explicit conversion constructors. Fixes bug #29000 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@278904 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/map b/include/map index b8aa7a6..bdde949 100644 --- a/include/map +++ b/include/map 
@@ -873,7 +873,7 @@    _LIBCPP_INLINE_VISIBILITY  explicit map(const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) {} + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}    template <class _InputIterator>  _LIBCPP_INLINE_VISIBILITY @@ -888,7 +888,7 @@  _LIBCPP_INLINE_VISIBILITY  map(_InputIterator __f, _InputIterator __l,  const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a))  {  insert(__f, __l);  } @@ -955,7 +955,7 @@    _LIBCPP_INLINE_VISIBILITY  map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a))  {  insert(__il.begin(), __il.end());  } @@ -977,13 +977,13 @@    _LIBCPP_INLINE_VISIBILITY  explicit map(const allocator_type& __a) - : __tree_(__a) + : __tree_(typename __base::allocator_type(__a))  {  }    _LIBCPP_INLINE_VISIBILITY  map(const map& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), __a) + : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))  {  insert(__m.begin(), __m.end());  } @@ -1034,7 +1034,7 @@  const mapped_type& at(const key_type& __k) const;    _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}  _LIBCPP_INLINE_VISIBILITY  key_compare key_comp() const {return __tree_.value_comp().key_comp();}  _LIBCPP_INLINE_VISIBILITY @@ -1367,7 +1367,7 @@    template <class _Key, class _Tp, class _Compare, class _Allocator>  map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) - : __tree_(_VSTD::move(__m.__tree_), __a) + : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))  {  if (__a != __m.get_allocator())  { @@ -1599,7 +1599,7 @@    _LIBCPP_INLINE_VISIBILITY  explicit multimap(const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) {} + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}    template <class _InputIterator>  _LIBCPP_INLINE_VISIBILITY @@ -1614,7 +1614,7 @@  _LIBCPP_INLINE_VISIBILITY  multimap(_InputIterator __f, _InputIterator __l,  const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a))  {  insert(__f, __l);  } @@ -1682,7 +1682,7 @@    _LIBCPP_INLINE_VISIBILITY  multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a))  {  insert(__il.begin(), __il.end());  } @@ -1704,13 +1704,13 @@    _LIBCPP_INLINE_VISIBILITY  explicit multimap(const allocator_type& __a) - : __tree_(__a) + : __tree_(typename __base::allocator_type(__a))  {  }    _LIBCPP_INLINE_VISIBILITY  multimap(const multimap& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), __a) + : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))  {  insert(__m.begin(), __m.end());  } @@ -1752,7 +1752,7 @@  size_type max_size() const _NOEXCEPT {return __tree_.max_size();}    _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}  _LIBCPP_INLINE_VISIBILITY  key_compare key_comp() const {return __tree_.value_comp().key_comp();}  _LIBCPP_INLINE_VISIBILITY @@ -1923,7 +1923,7 @@  #ifndef _LIBCPP_CXX03_LANG  template <class _Key, class _Tp, class _Compare, class _Allocator>  multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) - : __tree_(_VSTD::move(__m.__tree_), __a) + : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))  {  if (__a != __m.get_allocator())  { 
diff --git a/include/unordered_map b/include/unordered_map index bf64ad6..8d7edaf 100644 --- a/include/unordered_map +++ b/include/unordered_map 
@@ -1185,7 +1185,7 @@  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(  size_type __n, const hasher& __hf, const key_equal& __eql,  const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1197,7 +1197,7 @@  inline  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(  const allocator_type& __a) - : __table_(__a) + : __table_(typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1234,7 +1234,7 @@  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(  _InputIterator __first, _InputIterator __last, size_type __n,  const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1258,7 +1258,7 @@  template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(  const unordered_map& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) + : __table_(__u.__table_, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1285,7 +1285,7 @@  template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(  unordered_map&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) + : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1335,7 +1335,7 @@  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(  initializer_list<value_type> __il, size_type __n, const hasher& __hf,  const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1820,7 +1820,7 @@  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(  size_type __n, const hasher& __hf, const key_equal& __eql,  const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1858,7 +1858,7 @@  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(  _InputIterator __first, _InputIterator __last, size_type __n,  const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1871,7 +1871,7 @@  inline  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(  const allocator_type& __a) - : __table_(__a) + : __table_(typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1893,7 +1893,7 @@  template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(  const unordered_multimap& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) + : __table_(__u.__table_, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1920,7 +1920,7 @@  template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(  unordered_multimap&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) + : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); @@ -1972,7 +1972,7 @@  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(  initializer_list<value_type> __il, size_type __n, const hasher& __hf,  const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a))  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __get_db()->__insert_c(this); 
diff --git a/test/std/containers/associative/map/map.cons/alloc.pass.cpp b/test/std/containers/associative/map/map.cons/alloc.pass.cpp index 6ff102e..b1c60e0 100644 --- a/test/std/containers/associative/map/map.cons/alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/alloc.pass.cpp 
@@ -38,5 +38,13 @@  assert(m.begin() == m.end());  assert(m.get_allocator() == A());  } + { + typedef std::less<int> C; + typedef explicit_allocator<std::pair<const int, double> > A; + std::map<int, double, C, A> m(A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.get_allocator() == A()); + }  #endif  } 
diff --git a/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp index ea1374a..1325f47 100644 --- a/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp 
@@ -41,5 +41,14 @@  assert(m.key_comp() == C(4));  assert(m.get_allocator() == A());  } + { + typedef test_compare<std::less<int> > C; + typedef explicit_allocator<std::pair<const int, double> > A; + std::map<int, double, C, A> m(C(4), A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.key_comp() == C(4)); + assert(m.get_allocator() == A{}); + }  #endif  } 
diff --git a/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp index 8a9f7c8..8391eba 100644 --- a/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp 
@@ -91,5 +91,39 @@  assert(*next(mo.begin()) == V(2, 1));  assert(*next(mo.begin(), 2) == V(3, 1));  } + { + typedef std::pair<const int, double> V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + typedef test_compare<std::less<int> > C; + typedef explicit_allocator<V> A; + std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A{}); + std::map<int, double, C, A> m(mo, A{}); + assert(m.get_allocator() == A()); + assert(m.key_comp() == C(5)); + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + + assert(mo.get_allocator() == A()); + assert(mo.key_comp() == C(5)); + assert(mo.size() == 3); + assert(distance(mo.begin(), mo.end()) == 3); + assert(*mo.begin() == V(1, 1)); + assert(*next(mo.begin()) == V(2, 1)); + assert(*next(mo.begin(), 2) == V(3, 1)); + }  #endif  } 
diff --git a/test/std/containers/associative/map/map.cons/default.pass.cpp b/test/std/containers/associative/map/map.cons/default.pass.cpp index 265c59e..29cd4b4 100644 --- a/test/std/containers/associative/map/map.cons/default.pass.cpp +++ b/test/std/containers/associative/map/map.cons/default.pass.cpp 
@@ -32,6 +32,20 @@  assert(m.begin() == m.end());  }  { + typedef explicit_allocator<std::pair<const int, double>> A; + { + std::map<int, double, std::less<int>, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::map<int, double, std::less<int>, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + {  std::map<int, double> m = {};  assert(m.empty());  assert(m.begin() == m.end()); 
diff --git a/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp index 1210fe0..d7552b3 100644 --- a/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp 
@@ -69,7 +69,7 @@  assert(m.key_comp() == C(3));  assert(m.get_allocator() == A());  } -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11  {  typedef std::pair<const int, double> V;  typedef min_allocator<V> A; @@ -95,6 +95,30 @@  assert(m.get_allocator() == a);  }  #endif + { + typedef std::pair<const int, double> V; + typedef explicit_allocator<V> A; + typedef test_compare<std::less<int> > C; + A a; + std::map<int, double, C, A> m({ + {1, 1}, + {1, 1.5}, + {1, 2}, + {2, 1}, + {2, 1.5}, + {2, 2}, + {3, 1}, + {3, 1.5}, + {3, 2} + }, C(3), a); + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + assert(m.key_comp() == C(3)); + assert(m.get_allocator() == a); + }  #endif  #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS  } 
diff --git a/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp index 42376e2..6bad75d 100644 --- a/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp 
@@ -90,6 +90,7 @@  V(3, 1.5),  V(3, 2),  }; + {  typedef std::pair<const int, double> V;  typedef min_allocator<V> A;  typedef test_compare<std::less<int> > C; @@ -103,6 +104,21 @@  assert(*next(m.begin(), 2) == V(3, 1));  assert(m.get_allocator() == a);  } + { + typedef std::pair<const int, double> V; + typedef explicit_allocator<V> A; + typedef test_compare<std::less<int> > C; + A a; + std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), a ); + + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + assert(m.get_allocator() == a); + } + }  #endif  #endif  } 
diff --git a/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp index 4ccf561..8349f13 100644 --- a/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp 
@@ -229,6 +229,45 @@  assert(m3.key_comp() == C(5));  assert(m1.empty());  } + { + typedef std::pair<MoveOnly, MoveOnly> V; + typedef std::pair<const MoveOnly, MoveOnly> VC; + typedef test_compare<std::less<MoveOnly> > C; + typedef explicit_allocator<VC> A; + typedef std::map<MoveOnly, MoveOnly, C, A> M; + typedef std::move_iterator<V*> I; + V a1[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A{}); + V a2[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A{}); + M m3(std::move(m1), A{}); + assert(m3 == m2); + assert(m3.get_allocator() == A{}); + assert(m3.key_comp() == C(5)); + assert(m1.empty()); + }  #endif  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  } 
diff --git a/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp index 69660fc..40930f0 100644 --- a/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp 
@@ -38,5 +38,13 @@  assert(m.begin() == m.end());  assert(m.get_allocator() == A());  } + { + typedef std::less<int> C; + typedef explicit_allocator<std::pair<const int, double> > A; + std::multimap<int, double, C, A> m(A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.get_allocator() == A{}); + }  #endif  } 
diff --git a/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp index 8365328..fc6cef8 100644 --- a/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp 
@@ -41,5 +41,14 @@  assert(m.key_comp() == C(4));  assert(m.get_allocator() == A());  } + { + typedef test_compare<std::less<int> > C; + typedef explicit_allocator<std::pair<const int, double> > A; + std::multimap<int, double, C, A> m(C(4), A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.key_comp() == C(4)); + assert(m.get_allocator() == A{}); + }  #endif  } 
diff --git a/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp index 46b9459..cccebfb 100644 --- a/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp 
@@ -73,5 +73,30 @@  assert(mo.get_allocator() == A());  assert(mo.key_comp() == C(5));  } + { + typedef std::pair<const int, double> V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + typedef test_compare<std::less<int> > C; + typedef explicit_allocator<V> A; + std::multimap<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A{}); + std::multimap<int, double, C, A> m(mo, A{}); + assert(m == mo); + assert(m.get_allocator() == A{}); + assert(m.key_comp() == C(5)); + + assert(mo.get_allocator() == A{}); + assert(mo.key_comp() == C(5)); + }  #endif  } 
diff --git a/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp index d39cc1d..af1b22b 100644 --- a/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp 
@@ -32,6 +32,20 @@  assert(m.begin() == m.end());  }  { + typedef explicit_allocator<std::pair<const int, double>> A; + { + std::multimap<int, double, std::less<int>, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::multimap<int, double, std::less<int>, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + {  std::multimap<int, double> m = {};  assert(m.empty());  assert(m.begin() == m.end()); 
diff --git a/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp index f5d3463..8d12a05 100644 --- a/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp 
@@ -92,7 +92,7 @@  assert(m.key_comp() == Cmp(4));  assert(m.get_allocator() == A());  } -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11  {  typedef test_compare<std::less<int> > C;  typedef std::pair<const int, double> V; @@ -125,5 +125,39 @@  assert(m.get_allocator() == a);  }  #endif + { + typedef test_compare<std::less<int> > Cmp; + typedef explicit_allocator<std::pair<const int, double> > A; + typedef std::multimap<int, double, Cmp, A> C; + typedef C::value_type V; + C m( + { + {1, 1}, + {1, 1.5}, + {1, 2}, + {2, 1}, + {2, 1.5}, + {2, 2}, + {3, 1}, + {3, 1.5}, + {3, 2} + }, + Cmp(4), A{} + ); + assert(m.size() == 9); + assert(distance(m.begin(), m.end()) == 9); + C::const_iterator i = m.cbegin(); + assert(*i == V(1, 1)); + assert(*++i == V(1, 1.5)); + assert(*++i == V(1, 2)); + assert(*++i == V(2, 1)); + assert(*++i == V(2, 1.5)); + assert(*++i == V(2, 2)); + assert(*++i == V(3, 1)); + assert(*++i == V(3, 1.5)); + assert(*++i == V(3, 2)); + assert(m.key_comp() == Cmp(4)); + assert(m.get_allocator() == A{}); + }  #endif  } 
diff --git a/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp index 31bf72d..b0e70c4 100644 --- a/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp 
@@ -87,5 +87,36 @@  assert(*next(m.begin(), 7) == V(3, 1.5));  assert(*next(m.begin(), 8) == V(3, 2));  } + { + typedef std::pair<const int, double> V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + typedef test_compare<std::less<int> > C; + typedef explicit_allocator<V> A; + std::multimap<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A{}); + assert(m.get_allocator() == A{}); + assert(m.key_comp() == C(5)); + assert(m.size() == 9); + assert(distance(m.begin(), m.end()) == 9); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(1, 1.5)); + assert(*next(m.begin(), 2) == V(1, 2)); + assert(*next(m.begin(), 3) == V(2, 1)); + assert(*next(m.begin(), 4) == V(2, 1.5)); + assert(*next(m.begin(), 5) == V(2, 2)); + assert(*next(m.begin(), 6) == V(3, 1)); + assert(*next(m.begin(), 7) == V(3, 1.5)); + assert(*next(m.begin(), 8) == V(3, 2)); + }  #endif  } 
diff --git a/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp index 41771f6..6ce7127 100644 --- a/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp 
@@ -229,6 +229,45 @@  assert(m3.key_comp() == C(5));  assert(m1.empty());  } + { + typedef std::pair<MoveOnly, MoveOnly> V; + typedef std::pair<const MoveOnly, MoveOnly> VC; + typedef test_compare<std::less<MoveOnly> > C; + typedef explicit_allocator<VC> A; + typedef std::multimap<MoveOnly, MoveOnly, C, A> M; + typedef std::move_iterator<V*> I; + V a1[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A{}); + V a2[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A{}); + M m3(std::move(m1), A{}); + assert(m3 == m2); + assert(m3.get_allocator() == A{}); + assert(m3.key_comp() == C(5)); + assert(m1.empty()); + }  #endif  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  } 
diff --git a/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp index 0bc50ab..b5e063e 100644 --- a/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp 
@@ -32,6 +32,20 @@  assert(m.begin() == m.end());  }  { + typedef explicit_allocator<int> A; + { + std::multiset<int, std::less<int>, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::multiset<int, std::less<int>, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + {  std::multiset<int> m = {};  assert(m.empty());  assert(m.begin() == m.end()); 
diff --git a/test/std/containers/associative/set/set.cons/default.pass.cpp b/test/std/containers/associative/set/set.cons/default.pass.cpp index 4c924ca..3310c51 100644 --- a/test/std/containers/associative/set/set.cons/default.pass.cpp +++ b/test/std/containers/associative/set/set.cons/default.pass.cpp 
@@ -32,6 +32,20 @@  assert(m.begin() == m.end());  }  { + typedef explicit_allocator<int> A; + { + std::set<int, std::less<int>, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::set<int, std::less<int>, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + {  std::set<int> m = {};  assert(m.empty());  assert(m.begin() == m.end()); 
diff --git a/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp index 787c239..bd7db26 100644 --- a/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp 
@@ -34,5 +34,7 @@  #if TEST_STD_VER >= 11  test<int>(min_allocator<int>());  test<NotConstructible>(min_allocator<NotConstructible>{}); + test<int>(explicit_allocator<int>()); + test<NotConstructible>(explicit_allocator<NotConstructible>{});  #endif  } 
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp index 352945c..531afb2 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp 
@@ -37,5 +37,13 @@  assert(c.get_allocator() == A());  assert(c.empty());  } + { + typedef explicit_allocator<NotConstructible> A; + typedef A::value_type T; + typedef std::forward_list<T, A> C; + C c(A{}); + assert(c.get_allocator() == A()); + assert(c.empty()); + }  #endif  } 
diff --git a/test/std/containers/sequences/list/list.cons/default.pass.cpp b/test/std/containers/sequences/list/list.cons/default.pass.cpp index 3c1c2ef..ce04eef 100644 --- a/test/std/containers/sequences/list/list.cons/default.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/default.pass.cpp 
@@ -54,5 +54,15 @@  assert(l.size() == 0);  assert(std::distance(l.begin(), l.end()) == 0);  } + { + std::list<int, explicit_allocator<int>> l; + assert(l.size() == 0); + assert(std::distance(l.begin(), l.end()) == 0); + } + { + std::list<int, explicit_allocator<int>> l((explicit_allocator<int>())); + assert(l.size() == 0); + assert(std::distance(l.begin(), l.end()) == 0); + }  #endif  } 
diff --git a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp index 983d363..a18ba8f 100644 --- a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp 
@@ -66,5 +66,9 @@  test0<std::vector<bool, min_allocator<bool>> >();  test1<std::vector<bool, min_allocator<bool> > >(min_allocator<bool>());  } + { + test0<std::vector<bool, explicit_allocator<bool>> >(); + test1<std::vector<bool, explicit_allocator<bool> > >(explicit_allocator<bool>()); + }  #endif  } 
diff --git a/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp index e0542e7..4e6eb00 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp 
@@ -86,5 +86,17 @@  std::vector<int, min_allocator<int> > v;  assert(v.empty());  } + + { + test0<std::vector<int, explicit_allocator<int>> >(); + test0<std::vector<NotConstructible, explicit_allocator<NotConstructible>> >(); + test1<std::vector<int, explicit_allocator<int> > >(explicit_allocator<int>{}); + test1<std::vector<NotConstructible, explicit_allocator<NotConstructible> > > + (explicit_allocator<NotConstructible>{}); + } + { + std::vector<int, explicit_allocator<int> > v; + assert(v.empty()); + }  #endif  } 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp index 5253b60..6caa597 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp 
@@ -66,7 +66,25 @@  assert(c.load_factor() == 0);  assert(c.max_load_factor() == 1);  } -#if _LIBCPP_STD_VER > 11 + { + typedef explicit_allocator<std::pair<const NotConstructible, NotConstructible>> A; + typedef std::unordered_map<NotConstructible, NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + C c(A{}); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } +#if TEST_STD_VER > 11  {  typedef NotConstructible T;  typedef test_allocator<std::pair<const T, T>> A; 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp index 41bfc9d..6dd848a 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp 
@@ -108,5 +108,44 @@  assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_map<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + typedef std::pair<int, std::string> P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + C c(c0, A{}); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + }  #endif  } 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp index 8d309c8..04d172e 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp 
@@ -67,6 +67,39 @@  assert(c.max_load_factor() == 1);  }  { + typedef explicit_allocator<std::pair<const NotConstructible, NotConstructible>> A; + typedef std::unordered_map<NotConstructible, NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + {  std::unordered_map<int, int> c = {};  LIBCPP_ASSERT(c.bucket_count() == 0);  assert(c.size() == 0); 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp index 156bafb..e8d3562 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp 
@@ -104,6 +104,42 @@  assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_map<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + typedef std::pair<int, std::string> P; + C c({ + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }, + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + }  #endif  #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS  } 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp index 16586b3..58c9b51 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp 
@@ -154,6 +154,47 @@    assert(c0.empty());  } + { + typedef std::pair<int, std::string> P; + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_map<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + C c(std::move(c0), A{}); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + + assert(c0.empty()); + }  #endif  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  } 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp index f01efd0..890ed2e 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp 
@@ -111,5 +111,43 @@  assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_map<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + typedef std::pair<int, std::string> P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])), + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + }  #endif  } 
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp index 84d4795..58c397c 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp 
@@ -74,5 +74,27 @@  assert(c.load_factor() == 0);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const NotConstructible, NotConstructible> > A; + typedef std::unordered_map<NotConstructible, NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + C c(7, + test_hash<std::hash<NotConstructible> >(8), + test_compare<std::equal_to<NotConstructible> >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9)); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + }  #endif  } 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp index 2005f00..76a728e 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp 
@@ -66,6 +66,24 @@  assert(c.load_factor() == 0);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const NotConstructible, NotConstructible>> A; + typedef std::unordered_multimap<NotConstructible, NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + C c(A{}); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + }  #if _LIBCPP_STD_VER > 11  {  typedef NotConstructible T; 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp index b91aea0..bb577ea 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp 
@@ -136,5 +136,58 @@  assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_multimap<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + typedef std::pair<int, std::string> P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + C c(c0, A{}); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + C::const_iterator i = c.cbegin(); + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + ++i; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + ++i; + assert(i->first == 3); + assert(i->second == "three"); + ++i; + assert(i->first == 4); + assert(i->second == "four"); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + }  #endif  } 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp index 1cb2de7..8418c88 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp 
@@ -67,6 +67,39 @@  assert(c.max_load_factor() == 1);  }  { + typedef explicit_allocator<std::pair<const NotConstructible, NotConstructible>> A; + typedef std::unordered_multimap<NotConstructible, NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + {  std::unordered_multimap<int, int> c = {};  LIBCPP_ASSERT(c.bucket_count() == 0);  assert(c.size() == 0); 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp index a003196..79e6470 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp 
@@ -148,6 +148,65 @@  assert(c.key_eq() == test_compare<std::equal_to<int> >(9));  assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));  } + { + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_multimap<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + typedef std::pair<int, std::string> P; + C c({ + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }, + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + typedef std::pair<C::const_iterator, C::const_iterator> Eq; + Eq eq = c.equal_range(1); + assert(std::distance(eq.first, eq.second) == 2); + C::const_iterator i = eq.first; + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + eq = c.equal_range(2); + assert(std::distance(eq.first, eq.second) == 2); + i = eq.first; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + + eq = c.equal_range(3); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 3); + assert(i->second == "three"); + eq = c.equal_range(4); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 4); + assert(i->second == "four"); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + }  #endif  #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS  } 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp index 11942cf..b43ec08 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp 
@@ -225,6 +225,70 @@    assert(c0.empty());  } + { + typedef std::pair<int, std::string> P; + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_multimap<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + C c(std::move(c0), A()); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + typedef std::pair<C::const_iterator, C::const_iterator> Eq; + Eq eq = c.equal_range(1); + assert(std::distance(eq.first, eq.second) == 2); + C::const_iterator i = eq.first; + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + eq = c.equal_range(2); + assert(std::distance(eq.first, eq.second) == 2); + i = eq.first; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + + eq = c.equal_range(3); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 3); + assert(i->second == "three"); + eq = c.equal_range(4); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 4); + assert(i->second == "four"); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{}); + + assert(c0.empty()); + }  #endif  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  } 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp index f5b2bbe..7e2814f 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp 
@@ -155,5 +155,66 @@  assert(c.key_eq() == test_compare<std::equal_to<int> >(9));  assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));  } + { + typedef explicit_allocator<std::pair<const int, std::string>> A; + typedef std::unordered_multimap<int, std::string, + test_hash<std::hash<int> >, + test_compare<std::equal_to<int> >, + A + > C; + typedef std::pair<int, std::string> P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])), + 7, + test_hash<std::hash<int> >(8), + test_compare<std::equal_to<int> >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + typedef std::pair<C::const_iterator, C::const_iterator> Eq; + Eq eq = c.equal_range(1); + assert(std::distance(eq.first, eq.second) == 2); + C::const_iterator i = eq.first; + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + eq = c.equal_range(2); + assert(std::distance(eq.first, eq.second) == 2); + i = eq.first; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + + eq = c.equal_range(3); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 3); + assert(i->second == "three"); + eq = c.equal_range(4); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 4); + assert(i->second == "four"); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + assert(c.hash_function() == test_hash<std::hash<int> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); + assert(c.get_allocator() == A{});; + }  #endif  } 
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp index 764bf93..2b3b0e2 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp 
@@ -74,5 +74,27 @@  assert(c.load_factor() == 0);  assert(c.max_load_factor() == 1);  } + { + typedef explicit_allocator<std::pair<const NotConstructible, NotConstructible> > A; + typedef std::unordered_multimap<NotConstructible, NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + C c(7, + test_hash<std::hash<NotConstructible> >(8), + test_compare<std::equal_to<NotConstructible> >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8)); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9)); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + }  #endif  } 
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp index da6cbe8..4b4487f 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp 
@@ -63,6 +63,39 @@  assert(c.max_load_factor() == 1);  }  { + typedef explicit_allocator<NotConstructible> A; + typedef std::unordered_multiset<NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + {  std::unordered_multiset<int> c = {};  LIBCPP_ASSERT(c.bucket_count() == 0);  assert(c.size() == 0); 
diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp index 3af9095..81ad16b 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp 
@@ -63,6 +63,39 @@  assert(c.max_load_factor() == 1);  }  { + typedef explicit_allocator<NotConstructible> A; + typedef std::unordered_set<NotConstructible, + test_hash<std::hash<NotConstructible> >, + test_compare<std::equal_to<NotConstructible> >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { +	A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash<std::hash<NotConstructible> >()); + assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + {  std::unordered_set<int> c = {};  LIBCPP_ASSERT(c.bucket_count() == 0);  assert(c.size() == 0); 
diff --git a/test/std/strings/basic.string/string.cons/alloc.pass.cpp b/test/std/strings/basic.string/string.cons/alloc.pass.cpp index a803d33..81537ba 100644 --- a/test/std/strings/basic.string/string.cons/alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/alloc.pass.cpp 
@@ -91,5 +91,6 @@  test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();  #if TEST_STD_VER >= 11  test2<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >(); + test2<std::basic_string<char, std::char_traits<char>, explicit_allocator<char> > >();  #endif  } 
diff --git a/test/support/min_allocator.h b/test/support/min_allocator.h index 701159e..8e0afab 100644 --- a/test/support/min_allocator.h +++ b/test/support/min_allocator.h 
@@ -340,6 +340,31 @@  friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);}  };   +template <class T> +class explicit_allocator +{ +public: + typedef T value_type; + + explicit_allocator() TEST_NOEXCEPT {} + + template <class U> + explicit explicit_allocator(explicit_allocator<U>) TEST_NOEXCEPT {} + + T* allocate(std::size_t n) + { + return static_cast<T*>(::operator new(n*sizeof(T))); + } + + void deallocate(T* p, std::size_t) + { + return ::operator delete(static_cast<void*>(p)); + } + + friend bool operator==(explicit_allocator, explicit_allocator) {return true;} + friend bool operator!=(explicit_allocator x, explicit_allocator y) {return !(x == y);} +}; +  #endif // TEST_STD_VER >= 11    #endif // MIN_ALLOCATOR_H